package com.yinhai.message.core.bpo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.yinhai.core.app.api.util.JSonFactory;
import com.yinhai.core.common.api.base.IConstants;
import com.yinhai.core.common.api.config.impl.SysConfig;
import com.yinhai.core.common.api.util.ValidateUtil;
import com.yinhai.core.service.ta3.domain.service.TaBaseService;
import com.yinhai.message.api.bean.TMAppMessage;
import com.yinhai.message.api.bean.TMUser;
import com.yinhai.message.api.exception.TMException;
import com.yinhai.message.api.vo.TMMessageVo;
import com.yinhai.message.controller.UeditorFileVo;
import com.yinhai.message.core.adapterManager.AdapterManager;
import com.yinhai.message.core.po.MessageFilePo;
import com.yinhai.message.core.util.FTPUtils;
import com.yinhai.message.core.util.IMessageConstant;
import com.yinhai.message.manage.sysapp.bpo.ISysAppBpo;
import com.yinhai.message.manage.sysapp.vo.SysAppVo;
import com.yinhai.message.web.bpo.IMessageWebBpo;

public class MessageSendBpoImpl extends TaBaseService implements IMessageSendBpo {

	private Logger LOGGER = LoggerFactory.getLogger(this.getClass());
	 
	@Resource(name = "adapterManager")
	private AdapterManager adapterManager;
	
	@Resource(name = "messageBpo")
	private IMessageBpo messageBpo;
	
	@Resource(name = "sysAppBpo")
	private ISysAppBpo sysAppBpo;

	@Resource(name = "messageWebBpo")
	private IMessageWebBpo messageWebBpo;
	    
	@Override
	public void addMessageWidthFiles(String jsonStr, MultipartFile[] files,
			String realpath, String ticket) throws Exception {
		// 步骤1.校验数据
		TMMessageVo vo = jsonStrToVo(jsonStr);
		String appId = vo.getUser().getAppId();
		SysAppVo sysAppVo = sysAppBpo.getVoBySystemId(appId);
		// 验证接入系统的ticket
		if (!checkTicket(vo.getUser(), sysAppVo, ticket)) {
			throw new TMException("ticket 验证失败");
		}
		// 验证渠道
		validateSenderTypes(vo, sysAppVo);
		// 根据userid查询相关信息
//		messageWebBpo.buildSendTMUser(vo.getUser());
//		vo.setUserlist(messageWebBpo.buildTMUserListByVo(vo));
		// 步骤 2,3
		String mgid = messageBpo.saveMessage(vo);
		// 步骤4.如果有文件 上传文件服务器 将文件服务器上面的路径地址传到Vo里面 将上传到服务器上面的文件写入到数据库
		if (null != files && files.length > 0) {
			List<String> filesPaths = new ArrayList<>();
			int length = files.length;
			List<MessageFilePo> filePoList = new ArrayList<>();// 构造需要存储的文件对象
			for (int i = 0; i < length; i++) {
				MessageFilePo messageFilePo = new MessageFilePo();
				messageFilePo.setId(getStringSeq("SEQ_DEFAULT"));
				messageFilePo.setMsgid(mgid);// 消息id
				messageFilePo.setFilename(files[i].getOriginalFilename());// 上传源文件名称
				messageFilePo.setUploadsuccess(IConstants.COMMON_NO);// 上传成功标志
				String orignalfileName = files[i].getOriginalFilename();
				UUID uuid = UUID.randomUUID();// 假设返回UUID为存储 路径
				String storeMode = SysConfig.getSysConfig("msgFileStoreMode",
						"1");
				String storePath = SysConfig.getSysConfig("msgFileStorePath",
						"messagefilestorepath");
				messageFilePo.setFilestoremode(storeMode);// 文件存储模式
				if (IMessageConstant.MSG_FILE_STORE_LOCAL.equals(storeMode)) {// 存储到服务器本地
					String path = "";
					try {
						if (realpath.lastIndexOf("/") != -1) {
							realpath += File.separator + storePath;
						}
						// 应用真实跟目录+配置的存储路径+uuid+源文件名称
						path = realpath + storePath + File.separator
								+ uuid.toString();// 生成服务器存储路径
						saveFileToLocal(files[i].getInputStream(), path,
								orignalfileName);// 保存文件到服务器
						messageFilePo.setFilepath(path + File.separator
								+ orignalfileName);// 设置文件存储位置
					} catch (IOException e) {
						LOGGER.error("写文件失败");
						e.printStackTrace();
						throw new TMException("消息文件 上传失败  --" + e.getMessage());
					}
					filesPaths.add(path + File.separator + orignalfileName);
				} else if (IMessageConstant.MSG_FILE_STORE_FTPSERVER
						.equals(storeMode)) {
					FTPUtils ftpUtils = FTPUtils.getInstance();
					String serverName = SysConfig
							.getSysConfig("msgFileStorePlace");
					ftpUtils.storeFile(serverName, storePath, new String(
							orignalfileName.getBytes("GBK"), "iso-8859-1"),
							files[i].getInputStream());
					messageFilePo.setFilepath(storePath);// 设置文件存储位置
				} else if (IMessageConstant.MSG_FILE_STORE_UNIFIED_STORE
						.equals(storeMode)) {

				}
				messageFilePo.setUploadsuccess(IConstants.COMMON_YES);// 设置文件上传成功标志
				filePoList.add(messageFilePo);
			}
			messageBpo.batchSaveFile(filePoList);
			// 设置上传文件存储到服务的路径地址
			vo.getMessage().setFiles(null);// 设置文件为空
		}
		// 步骤5.添加到adaper里面去
		adapterManager.adapter(vo);
	}

	private void validateSenderTypes(TMMessageVo vo, SysAppVo sysAppVo)
			throws Exception {
		String senderTypeOrder = sysAppVo != null ? sysAppVo
				.getSenderTypeOrder() : "";
		if (!StringUtils.isEmpty(senderTypeOrder)) {
			String[] split = senderTypeOrder.split(",");
			List<String> types = vo.getMessage().getMessageTypes();
			if (CollectionUtils.isEmpty(types)) {
				// 验证传过去的type若为空，则取渠道优先顺序第一个
				List<String> messageTypes = new ArrayList<>();
				messageTypes.add(split[0]);
				vo.getMessage().setMessageTypes(messageTypes);
			} else {
				// 验证传过去的type是否在发送者所在接入系统渠道允许中
				for (String t : types) {
					if (!Arrays.asList(split).contains(t)) {
						throw new TMException("发送错误，传入的消息发送类型不在接入系统的渠道内");
					}
				}
			}
		} else {
			throw new TMException("发送错误，接入系统的渠道为空");
		}
	}

	@Override
	public void addMessageWidthServerFiles(String jsonStr,
			List<UeditorFileVo> ufiles, String realPath) throws Exception {
		// 步骤1.校验数据
		TMMessageVo vo = jsonStrToVo(jsonStr);
		// 验证渠道
		String appId = vo.getUser().getAppId();
		SysAppVo sysAppVo = sysAppBpo.getVoBySystemId(appId);
		validateSenderTypes(vo, sysAppVo);
		// 根据userid查询相关信息
//		messageWebBpo.buildSendTMUser(vo.getUser());
//		vo.setUserlist(messageWebBpo.buildTMUserListByVo(vo));
		// 步骤2,3
		String mgid = messageBpo.saveMessage(vo);
		// 步骤4.如果有文件 上传文件服务器 将文件服务器上面的路径地址传到Vo里面 将上传到服务器上面的文件写入到数据库
		if (null != ufiles && ufiles.size() > 0) {
			List<MessageFilePo> filePoList = new ArrayList<>();// 构造需要存储的文件对象
			for (UeditorFileVo u : ufiles) {
				MessageFilePo messageFilePo = new MessageFilePo();
				messageFilePo.setId(getStringSeq("SEQ_DEFAULT"));
				messageFilePo.setMsgid(mgid);// 消息id
				messageFilePo.setFilename(u.getName());// 上传源文件名称
				messageFilePo.setUploadsuccess(IConstants.COMMON_NO);// 上传成功标志
				String storeMode = SysConfig.getSysConfig("msgFileStoreMode",
						"1");
				String storePath = SysConfig.getSysConfig("msgFileStorePath",
						"messagefilestorepath");
				messageFilePo.setFilestoremode(storeMode);// 文件存储模式
				if (IMessageConstant.MSG_FILE_STORE_LOCAL.equals(storeMode)) {// 存储到服务器本地
					messageFilePo.setFilepath(u.getPath());// 设置文件存储位置
				} else if (IMessageConstant.MSG_FILE_STORE_FTPSERVER
						.equals(storeMode)) {
					FTPUtils ftpUtils = FTPUtils.getInstance();
					String serverName = SysConfig
							.getSysConfig("msgFileStorePlace");
					ftpUtils.storeFile(serverName, storePath, new String(u
							.getName().getBytes("GBK"), "iso-8859-1"),
							new FileInputStream(u.getPath()));
					messageFilePo.setFilepath(storePath);// 设置文件存储位置
				} else if (IMessageConstant.MSG_FILE_STORE_UNIFIED_STORE
						.equals(storeMode)) {

				}
				messageFilePo.setUploadsuccess(IConstants.COMMON_YES);// 设置文件上传成功标志
				filePoList.add(messageFilePo);
			}
			messageBpo.batchSaveFile(filePoList);
			// 设置上传文件存储到服务的路径地址
			vo.getMessage().setFiles(null);// 设置文件为空
		}
		// 步骤5.添加到adaper里面去
		adapterManager.adapter(vo);
	}

	/**
	 * jsonStr 转成 AMQMessageVo
	 * 
	 * @param jsonStr
	 * @return
	 * @throws Exception
	 */
	TMMessageVo jsonStrToVo(String jsonStr) throws Exception {
		TMMessageVo vo = null;
		if (ValidateUtil.isNotEmpty(jsonStr)) {
			vo = JSonFactory.json2bean(jsonStr, TMMessageVo.class);
			if (vo != null && vo.getUser() != null && vo.getUserlist() != null
					&& vo.getMessage() != null) {
				vo.getMessage().setMgid(getSysStrDate().substring(0, 4)+getStringSeq("SEQ_MESSAGE"));
			} else {
				throw new TMException("发送人或接收人或消息为空");
			}
		} else {
			throw new TMException("传入json字符串为空,请检查字符串，重新发送");
		}
		return vo;
	}
	
	/**
     * 验证接入系统的ticket
     * @param user
     * @param sysAppVo
     * @param ticket
     * @return
	 */
    boolean checkTicket(TMUser user, SysAppVo sysAppVo, String ticket) {
        boolean result = false;
		String appid = user.getAppId();
		if(appid!=null){
            result = sysAppVo != null ? sysAppVo.getTicket().equals(ticket) : false;
        }
		return result;
	}
    
    /**
     * 保存文件到服务器本地
     *
     * @param ins
     * @param path
     * @return
     */
    private void saveFileToLocal(InputStream ins, String path,String orignalfileName) throws IOException {
       String filePath = "";
        File fileDir  = new File(path);
        if(!fileDir.exists()){
            fileDir.mkdirs();
        }
        if (File.separator.startsWith(path)) {
            filePath = path + orignalfileName;
        } else {
            filePath = path + File.separator +orignalfileName;
        }
        File fileToSave = new File(filePath);
        OutputStream ous = null;
        if (!fileToSave.exists()) {
        	fileToSave.createNewFile();
        }
        if (ins != null) {
			ous = new FileOutputStream(fileToSave);
			byte[] bt = new byte[1024];
			int length = 0;
			while ((length = ins.read(bt)) != -1) {
				ous.write(bt, 0, length);
			}
			ins.close();
			ous.close();
        }
    }

    /**
     * app 
     */
	@Override
	public void addAppMesssage(String jsonStr, String aac001s) throws Exception {
		TMAppMessage appMessage = jsonStrToAppMessage(jsonStr);
		messageBpo.addAppMessage(appMessage,aac001s);
	}
	
	TMAppMessage jsonStrToAppMessage(String jsonStr){
		TMAppMessage appMessage = null;
		if (ValidateUtil.isNotEmpty(jsonStr)) {
			appMessage = JSonFactory.json2bean(jsonStr, TMAppMessage.class);
			if (appMessage != null && appMessage.getTitle() != null && appMessage.getContent() != null) {
				
			} else {
				throw new TMException("app消息的titie或content为空");
			}
		} else {
			throw new TMException("传入json字符串为空,请检查字符串，重新发送");
		}
		return appMessage;
	}
}
